﻿using System;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
using System.Threading;
using NetMicro.EventBus.Persistences;
using MySqlConnector;
using Microsoft.CodeAnalysis;

namespace NetMicro.EventBus.MySql
{
    public class MySqlMessageStorageInitializer : IMessageStorageInitializer
    {
        public MySqlMessageStorageInitializer(IOptionsMonitor<EventBusMySqlOptions> options)
        {
            Options = options;
        }

        private IOptionsMonitor<EventBusMySqlOptions> Options { get; }
        public async Task InitializeAsync(CancellationToken cancellationToken = default)
        {
            var sql = $@"
CREATE TABLE IF NOT EXISTS `{Options.CurrentValue.RetryTableName}`
(
	`Id` BIGINT AUTO_INCREMENT PRIMARY KEY,
	`EventBody` LONGTEXT NOT NULL,
	`CreateTime` BIGINT NOT NULL,
	`DelayAt` BIGINT NOT NULL,
	`ExpireTime` BIGINT NOT NULL,
	`RetryCount` INT NOT NULL,
	`IsLocking`  TINYINT NOT NULL,
	`LockEnd` BIGINT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


CREATE TABLE IF NOT EXISTS `{Options.CurrentValue.DelayTableName}`
(
	`Id` BIGINT AUTO_INCREMENT PRIMARY KEY,
	`EventBody` LONGTEXT NOT NULL,
	`CreateTime` BIGINT NOT NULL,
	`DelayAt` BIGINT NOT NULL,
	`ExpireTime` BIGINT NOT NULL,
	`RetryCount` INT NOT NULL,
	`IsLocking` TINYINT NOT NULL,
	`LockEnd` BIGINT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


CREATE TABLE IF NOT EXISTS `{Options.CurrentValue.DeadLetterTableName}`
(
	`Id` BIGINT AUTO_INCREMENT PRIMARY KEY,
	`EventBody` LONGTEXT NOT NULL,
	`CreateTime` BIGINT NOT NULL,
	`ExpireTime` BIGINT NOT NULL,
	`EventName` varchar(400) NOT NULL,
	`Version` varchar(50) NOT NULL,
	`EventHandlerName` varchar(400) NOT NULL,
	`MsgId` varchar(100) NOT NULL,
	`Exception` LONGTEXT NOT NULL,
	`RetryCount` INT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
";


       

        await using var connection = new MySqlConnection(Options.CurrentValue.ConnectionString);
            await connection.OpenAsync(cancellationToken).ConfigureAwait(false);
            await using var cmd = connection.CreateCommand();
            cmd.CommandText = sql;
            await cmd.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
        }
    }
}
